import { AdminRole } from '../generated/prisma'
import { resultFailure, resultSuccess } from '../utils/resultFormatter'
import { prisma } from './index.repo'

/**
 * ==================== AdminOrganization 管理 ====================
 * 管理管理员和组织之间的关联关系
 */

/**
 * 将管理员添加到组织
 * @param adminId 管理员ID
 * @param organizationId 组织ID
 * @param role 管理员角色（默认为 ORGANIZATION_ADMIN）
 */
export const addAdminToOrganization = async (
    adminId: string,
    organizationId: string,
    role: AdminRole = AdminRole.ORGANIZATION_ADMIN
) => {
    try {
        const result = await prisma.adminOrganization.create({
            data: {
                adminId,
                organizationId,
                role
            }
        })

        return resultSuccess(true, 201, result, 'Admin added to organization successfully')
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}

/**
 * 批量将管理员添加到组织
 * @param adminIds 管理员ID列表
 * @param organizationId 组织ID
 * @param role 管理员角色（默认为 ORGANIZATION_ADMIN）
 */
export const addAdminsToOrganization = async (
    adminIds: string[],
    organizationId: string,
    role: AdminRole = AdminRole.ORGANIZATION_ADMIN
) => {
    try {
        const result = await prisma.adminOrganization.createMany({
            data: adminIds.map(adminId => ({
                adminId,
                organizationId,
                role
            })),
            skipDuplicates: true
        })

        return resultSuccess(true, 201, result, `${result.count} admins added to organization successfully`)
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}

/**
 * 从组织中移除管理员
 * @param adminId 管理员ID
 * @param organizationId 组织ID
 */
export const removeAdminFromOrganization = async (adminId: string, organizationId: string) => {
    try {
        const result = await prisma.adminOrganization.updateMany({
            where: {
                adminId,
                organizationId
            },
            data: {
                deletedAt: new Date()
            }
        })

        if (result.count === 0) {
            return resultFailure(false, 404, 'Admin-Organization association not found')
        }

        return resultSuccess(true, 200, result, 'Admin removed from organization successfully')
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}

/**
 * 批量从组织中移除管理员
 * @param adminIds 管理员ID列表
 * @param organizationId 组织ID
 */
export const removeAdminsFromOrganization = async (adminIds: string[], organizationId: string) => {
    try {
        const result = await prisma.adminOrganization.updateMany({
            where: {
                adminId: { in: adminIds },
                organizationId
            },
            data: {
                deletedAt: new Date()
            }
        })

        return resultSuccess(true, 200, result, `${result.count} admins removed from organization successfully`)
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}

/**
 * 更新管理员在组织中的角色
 * @param adminId 管理员ID
 * @param organizationId 组织ID
 * @param role 新的角色
 */
export const updateAdminOrganizationRole = async (adminId: string, organizationId: string, role: AdminRole) => {
    try {
        const result = await prisma.adminOrganization.updateMany({
            where: {
                adminId,
                organizationId,
                deletedAt: null
            },
            data: {
                role
            }
        })

        if (result.count === 0) {
            return resultFailure(false, 404, 'Admin-Organization association not found')
        }

        return resultSuccess(true, 200, result, 'Admin role updated successfully')
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}

/**
 * 读取组织的所有管理员
 * @param organizationId 组织ID
 * @param offset 偏移量
 * @param limit 限制数量
 */
export const readOrganizationAdmins = async (organizationId: string, offset: number = 0, limit: number = 10) => {
    try {
        const total = await prisma.adminOrganization.count({
            where: { organizationId, deletedAt: null }
        })

        const result = await prisma.adminOrganization.findMany({
            where: { organizationId, deletedAt: null },
            skip: offset,
            take: limit,
            include: {
                admin: {
                    select: {
                        id: true,
                        username: true,
                        email: true,
                        phone: true,
                        createdAt: true,
                        updatedAt: true
                    }
                }
            }
        })

        return resultSuccess(true, 200, { total, result })
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}

/**
 * 读取管理员管理的所有组织
 * @param adminId 管理员ID
 * @param offset 偏移量
 * @param limit 限制数量
 */
export const readAdminOrganizations = async (adminId: string, offset: number = 0, limit: number = 10) => {
    try {
        const total = await prisma.adminOrganization.count({
            where: { adminId, deletedAt: null }
        })

        const result = await prisma.adminOrganization.findMany({
            where: { adminId, deletedAt: null },
            skip: offset,
            take: limit,
            include: {
                organization: {
                    select: {
                        id: true,
                        name: true,
                        description: true,
                        createdAt: true,
                        updatedAt: true
                    }
                }
            }
        })

        return resultSuccess(true, 200, { total, result })
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}

/**
 * 检查管理员是否有组织的权限
 * @param adminId 管理员ID
 * @param organizationId 组织ID
 */
export const checkAdminOrganizationPermission = async (adminId: string, organizationId: string) => {
    try {
        const result = await prisma.adminOrganization.findFirst({
            where: {
                adminId,
                organizationId,
                deletedAt: null
            }
        })

        if (!result) {
            return resultFailure(false, 403, 'Admin does not have permission for this organization')
        }

        return resultSuccess(true, 200, result, 'Admin has permission')
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}

/**
 * 检查管理员是否是全局管理员
 * @param adminId 管理员ID
 * @param organizationId 组织ID
 */
export const checkIsGlobalAdmin = async (adminId: string, organizationId: string) => {
    try {
        const result = await prisma.adminOrganization.findFirst({
            where: {
                adminId,
                organizationId,
                role: AdminRole.GLOBAL_ADMIN,
                deletedAt: null
            }
        })

        if (!result) {
            return resultFailure(false, 403, 'Admin is not a global admin')
        }

        return resultSuccess(true, 200, true, 'Admin is a global admin')
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}

/**
 * 同步组织的管理员列表（删除旧的，添加新的）
 * @param organizationId 组织ID
 * @param adminConfigs 管理员配置列表 [{ adminId, role }]
 */
export const syncOrganizationAdmins = async (
    organizationId: string,
    adminConfigs: Array<{ adminId: string; role: AdminRole }>
) => {
    try {
        const result = await prisma.$transaction(async tx => {
            // 软删除所有现有的管理员关联
            await tx.adminOrganization.updateMany({
                where: { organizationId },
                data: { deletedAt: new Date() }
            })

            // 添加新的管理员关联
            const created = await tx.adminOrganization.createMany({
                data: adminConfigs.map(config => ({
                    adminId: config.adminId,
                    organizationId,
                    role: config.role
                })),
                skipDuplicates: true
            })

            return created
        })

        return resultSuccess(true, 200, result, `Organization admins synchronized successfully`)
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}
